package com.tanchengjin.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanchengjin.admin.SystemConstants;
import com.tanchengjin.admin.model.dao.*;
import com.tanchengjin.admin.exception.SystemException;
import com.tanchengjin.admin.model.pojo.*;
import com.tanchengjin.admin.model.vo.AdministratorVO;
import com.tanchengjin.admin.service.*;
import com.tanchengjin.admin.utils.IntUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.security.Permission;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class AdministratorServiceImpl implements AdministratorService {
    private final static Logger logger = LoggerFactory.getLogger(AdministratorServiceImpl.class);

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AdminUserMapper adminUserMapper;
    @Autowired
    private AdminUserRoleMapper adminUserRoleMapper;
    @Autowired
    private AdminRoleMapper adminRoleMapper;
    @Autowired
    private AdminRolePermissionMapper adminRolePermissionMapper;
    @Autowired
    private AdminPermissionMapper adminPermissionMapper;
    @Autowired
    private AdminMenuMapper adminMenuMapper;
    @Autowired
    private AdminPermissionMenuMapper adminPermissionMenuMapper;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private AdminMenuService adminMenuService;
    @Autowired
    private AdminPermissionService adminPermissionService;
    @Autowired
    private AdminUserRoleService adminUserRoleService;
    @Autowired
    private AdminRoleService adminRoleService;

    @Override
    @Transactional
    public int createAdminUser(AdminUser adminUser, int[] roles) {

        adminUser.setPassword(passwordEncoder.encode(adminUser.getPassword()));

        int i = adminUserMapper.insertSelective(adminUser);

        //创建管理员角色
        int c = createAdminUserRole(roles, adminUser.getId());

        return i;
    }

    /**
     * 添加管理员用户角色
     */
    @Override
    public int createAdminUserRole(int[] roles, int aid) {
        deleteRoleByAdminId(aid);
        int i = 0;
        //创建管理员角色
        if (roles != null) {
            //批量创建角色
            for (int rid : roles) {
                AdminRole adminRole = adminRoleMapper.selectByPrimaryKey(rid);
                if (adminRole == null) {
                    logger.error("为管理员: " + aid + " 添加不存在的管理员角色----ID: " + rid);
                } else {
                    AdminUserRole adminUserRole = new AdminUserRole();
                    adminUserRole.setAdminRoleId(rid);
                    adminUserRole.setAdminUserId(aid);
                    i += adminUserRoleMapper.insertSelective(adminUserRole);
                }
            }
        }
        return i;
    }

    /**
     * 删除管理员所有角色
     */
    @Override
    public int deleteRoleByAdminId(int adminId) {
        int i = 0;
        List<AdminUserRole> adminUserRoleList = adminUserRoleMapper.selectByAdminUserId(adminId);
        for (AdminUserRole adminUserRole : adminUserRoleList) {
            i += adminUserRoleMapper.deleteByPrimaryKey(adminUserRole.getId());
        }
        return i;
    }

    /**
     * 批量删除管理员
     */
    @Override
    public int batchDelete(int[] ids) {
        int i = 0;
        //系统默认管理员禁止删除
        int[] n_ids = IntUtil.excludeByKey(ids, 1);
        if (n_ids.length >= 1) {
            i = adminUserMapper.batchDeleteByPrimaryKey(n_ids);
        }
        return i;
    }

    @Override
    public List<AdminUserRole> getRoleByAdminId(int id) {
        List<AdminUserRole> adminUserRoleList = adminUserRoleMapper.selectByAdminUserId(id);
        return adminUserRoleList;
    }


    /**
     * 通过角色ID获取对应的权限
     */
    @Override
    public List<AdminPermission> getPermissionByRoleId(int roleId) {
        ArrayList<AdminPermission> adminPermissions = new ArrayList<>();
        //得到角色权限表
        List<AdminRolePermission> adminRolePermissions = adminRolePermissionMapper.selectByRoleId(roleId);
        //通过角色权限表获取对应的权限
        for (AdminRolePermission adminRolePermission : adminRolePermissions) {
            //得到所有权限
            AdminPermission adminPermission = adminPermissionMapper.selectByPrimaryKey(adminRolePermission.getAdminPermissionId());
            adminPermissions.add(adminPermission);
        }
        return adminPermissions;
    }

    /**
     * 通过管理员ID获取对应的权限
     */
    @Override
    public List<AdminPermission> getPermissionByAdminId(int id) {
        ArrayList<AdminPermission> adminPermissionList = new ArrayList<>();
        //获取管理员角色
        List<AdminUserRole> adminUserRoleList = adminUserRoleMapper.selectByAdminUserId(id);
        //通过角色获取对应的权限
        for (AdminUserRole adminUserRole : adminUserRoleList) {
            List<AdminPermission> permissionList = this.getPermissionByRoleId(adminUserRole.getAdminRoleId());
            adminPermissionList.addAll(permissionList);
        }
        return adminPermissionList;
    }

    /**
     * 创建管理员角色
     */
    @Override
    @Transactional
    public int createAdminRole(AdminRole adminRole) {
        int i = adminRoleMapper.insertSelective(adminRole);
//        this.createAdminRolePermission(adminRole.getPermissionIds(), adminRole.getId());
//        adminRole.getPermissionIds();
        return i;
    }

    /**
     * 创建角色权限
     */
    @Override
    public int createAdminRolePermission(Integer[] permissionIds, int roleId) {
        int i = 0;
        for (Integer pid : permissionIds) {
            AdminRolePermission adminRolePermission = new AdminRolePermission();
            adminRolePermission.setAdminPermissionId(pid);
            adminRolePermission.setAdminRoleId(roleId);
            i += adminRolePermissionMapper.insertSelective(adminRolePermission);
        }
        return i;
    }

    //获取当前表内所有权限
    @Override
    public List<AdminPermission> getAdminPermissionList() {
        List<AdminPermission> all = adminPermissionMapper.getAll();
        return all;
    }


    /**
     * 获取当前管理员的左侧菜单树
     *
     * @param id int
     * @return List
     */
    @Deprecated
    public List<AdminMenu> getAdminMenuTree(int id) {
        AdminUser adminUser = adminUserMapper.selectByPrimaryKey(id);
        if (adminUser == null) throw new SystemException("不存在的管理员");

        //查找当前管理的所有权限
        List<AdminPermission> adminPermissionList = getAdminPermissionList();
        List<AdminMenu> adminMenuList = new ArrayList<>();
        for (AdminPermission adminPermission : adminPermissionList) {
            //获取所有的权限菜单表
            List<AdminPermissionMenu> adminPermissionMenus = adminPermissionMenuMapper.selectByPermissionId(adminPermission.getId());
            for (AdminPermissionMenu adminPermissionMenu : adminPermissionMenus) {
                AdminMenu adminMenu = adminMenuMapper.selectByPrimaryKey(adminPermissionMenu.getAdminMenuId());
                adminMenuList.add(adminMenu);
            }
        }
        return adminMenuList;
    }

    /**
     * 获取当前已经登陆的管理员
     */
    @Override
    public AdminUser getCurrentUser() {
        AdminUser adminUser = new AdminUser();
        Object attribute = request.getSession().getAttribute(SystemConstants.adminUserSessionKey);
        if (attribute == null) throw new SystemException("not login");
        if (attribute instanceof AdminUser) {
            adminUser = (AdminUser) attribute;
        }
        return adminUser;
    }

    @Override
    public List<AdminMenu> getCurrentAdminMenuList() {
        Integer id = getCurrentUser().getId();
        if (id == 1) {
            //超级管理员获取全部的菜单
            return adminMenuService.getNodeTree();
        }
        List<AdminMenu> adminMenus = new ArrayList<>();
        adminMenus = adminMenuService.getMenuTreeByAdminId(id);
        return adminMenus;
    }

    /**
     * 当前管理员的相关信息
     */
    public AdminUserExtension getAdminDetails() {
        AdminUserExtension adminUserExtension = adminUserMapper.selectAdminDetailsById(getCurrentUser().getId());
        return adminUserExtension;
    }

    @Override
    public AdministratorVO getAdmin() {
//        AdministratorVO adminInMemory = getAdminInMemory();
//        if (adminInMemory == null) {
        AdministratorVO administratorVO = new AdministratorVO();
        administratorVO.setUserinfo(getCurrentUser());
        administratorVO.setMenus(getCurrentAdminMenuList());
        //cache
//            this.request.getSession().setAttribute(SystemConstants.adminSessionKey, administratorVO);
        return administratorVO;
//        } else {
//            return adminInMemory;
//        }
    }

//    private AdministratorVO getAdminInMemory() {
//        AdministratorVO administratorVO = null;
//
//        Object attribute = this.request.getSession().getAttribute(SystemConstants.adminSessionKey);
//        if (attribute == null) return administratorVO;
//        if (attribute instanceof AdministratorVO) {
//            administratorVO = (AdministratorVO) attribute;
//        }
//        return administratorVO;
//    }


    @Override
    public int changePassword(int adminId, String password) {
        int i = 0;
        AdminUser adminUser = new AdminUser();
        adminUser.setId(adminId);
        adminUser.setPassword(password);
        i += adminUserMapper.updateByPrimaryKeySelective(adminUser);
        return i;
    }

    @Override
    @Transactional
    public int allocPermission(int roleId, List<Integer> menuIds) {
        //清空role_permission角色权限表
        int i = adminRolePermissionMapper.flushAllByRoleId(roleId);

        //通过菜单寻找相应的权限，并批量写入到role_permission表中
        List<AdminPermissionMenu> permissionList = adminPermissionMenuMapper.selectByMenuIds(menuIds);

        List<Integer> permissionIds = new ArrayList<>();
        //获取菜单的所有权限，并去除重复值
        permissionList.stream().filter(e -> {
            return !permissionIds.contains(e.getAdminPermissionId());
        }).forEach(e -> {
            permissionIds.add(e.getAdminPermissionId());
        });
        return adminRolePermissionMapper.batchInsert(roleId, permissionIds);
    }

    @Override
    public List<AdminMenu> getMenu() {
        List<AdminMenu> adminMenus = adminMenuMapper.selectByAdminId(getUser().getId(), "id", "desc");
        return adminMenus;
    }

    @Override
    public AdminUser getUser() {
        AdminUser adminUser = new AdminUser();
        Object attribute = request.getSession().getAttribute(SystemConstants.adminUserSessionKey);
        if (attribute == null) throw new SystemException("not login");
        if (attribute instanceof AdminUser) {
            adminUser = (AdminUser) attribute;
        }
        return adminUser;
    }

    @Override
    public List<AdminPermission> getMenuTree() {
        return adminPermissionService.getMenuTree();
    }

    @Override
    public List<AdminPermission> getIdentifierPermission() {
        //获取当前用户的所有角色id
        List<Integer> ids = adminRoleService.getIdsBySysUserId(getCurrentUser().getId());

        String idsStr = String.join(",", ids.stream().map(String::valueOf).collect(Collectors.toList()));
        //通过角色id获取所拥有的全部标识权限
        QueryWrapper<AdminPermission> adminPermissionQueryWrapper = new QueryWrapper<>();
        adminPermissionQueryWrapper.select("*");
        adminPermissionQueryWrapper.apply("id in (select admin_permission_id from admin_role_permission where admin_role_id in ({0})) and type = 3", idsStr);
        List<AdminPermission> list = adminPermissionService.list(adminPermissionQueryWrapper);
        return list;
    }

    @Override
    public List<AdminRole> getRoles() {
        QueryWrapper<AdminRole> adminRoleQueryWrapper = new QueryWrapper<>();
        adminRoleQueryWrapper.in("id", getRoleIds());
        List<AdminRole> list = adminRoleService.list(adminRoleQueryWrapper);
        return list;
    }

    @Override
    public List<Integer> getRoleIds() {
        QueryWrapper<AdminUserRole> adminUserRoleQueryWrapper = new QueryWrapper<>();
        adminUserRoleQueryWrapper.eq("admin_user_id", getId());
        List<AdminUserRole> list = adminUserRoleService.list(adminUserRoleQueryWrapper);
        return list.stream().map(AdminUserRole::getAdminRoleId).collect(Collectors.toList());
    }

    @Override
    public Integer getId() {
        return getCurrentUser().getId();
    }

    @Override
    public List<AdminPermission> getPermissions() {
        return adminPermissionService.getPermissionsByRoleIds(getRoleIds());
    }
}
